/*
 * JNIWrapper.h  0.4.0 / Nov 14, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#ifndef JNIWRAPPER_H
#define JNIWRAPPER_H

#include "Cute4jCommon.h"

// JNIWrapper Class. -----------------------------------------------------------

/*!
 * \brief JVM Wrapper.
 *
 * \author Slobodan Vrkacevic
 * \version 0.4.0
 */
class CUTE4J_EXPORT JNIWrapper
{
public:
  static void checkException(JNIEnv *env);
  static bool testException(JNIEnv *env);
  static void fatalError(JNIEnv *env, const char *errorMessage);
  static void throwInternalError(JNIEnv *env, const char *errorMessage = 0);
  static void throwOutOfMemoryError(JNIEnv *env, const char *errorMessage = 0);
  static void throwRuntimeExcpetion(JNIEnv *env,
                                    const char *exceptionMessage = 0);
  static jfieldID getFieldID(JNIEnv *env, jclass cls, const char *name,
                             const char *sig);
  static jfieldID getStaticFieldID(JNIEnv *env, jclass cls, const char *name,
                                   const char *sig);
  static jmethodID getMethodID(JNIEnv *env, jclass cls, const char *name,
                               const char *sig);
  static jmethodID getStaticMethodID(JNIEnv *env, jclass cls, const char *name,
                                     const char *sig);
  static jobject getObjectField(JNIEnv *env, jobject obj, jfieldID fieldID);
  static void setObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
                             jobject val);
  static jboolean getBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID);
  static void setBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID,
                              jboolean val);
  static jbyte getByteField(JNIEnv *env, jobject obj, jfieldID fieldID);
  static void setByteField(JNIEnv *env, jobject obj, jfieldID fieldID,
                           jbyte val);
  static jchar getCharField(JNIEnv *env, jobject obj, jfieldID fieldID);
  static void setCharField(JNIEnv *env, jobject obj, jfieldID fieldID,
                           jchar val);
  static jshort getShortField(JNIEnv *env, jobject obj, jfieldID fieldID);
  static void setShortField(JNIEnv *env, jobject obj, jfieldID fieldID,
                            jshort val);
  static jint getIntField(JNIEnv *env, jobject obj, jfieldID fieldID);
  static void setIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint val);
  static jlong getLongField(JNIEnv *env, jobject obj, jfieldID fieldID);
  static void setLongField(JNIEnv *env, jobject obj, jfieldID fieldID,
                           jlong val);
  static jfloat getFloatField(JNIEnv *env, jobject obj, jfieldID fieldID);
  static void setFloatField(JNIEnv *env, jobject obj, jfieldID fieldID,
                            jfloat val);
  static jdouble getDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID);
  static void setDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID,
                            jdouble val);
  static bool callObjectMethod(JNIEnv *env, jobject &result, jobject obj,
                               jmethodID methodID, va_list &args);
  static bool callObjectMethod(JNIEnv *env, jobject &result, jobject obj,
                               jmethodID methodID, ...);
  static bool callBooleanMethod(JNIEnv *env, jboolean &result, jobject obj,
                                jmethodID methodID, va_list &args);
  static bool callBooleanMethod(JNIEnv *env, jboolean &result, jobject obj,
                                jmethodID methodID, ...);
  static bool callByteMethod(JNIEnv *env, jbyte &result, jobject obj,
                             jmethodID methodID, va_list &args);
  static bool callByteMethod(JNIEnv *env, jbyte &result, jobject obj,
                             jmethodID methodID, ...);
  static bool callCharMethod(JNIEnv *env, jchar &result, jobject obj,
                             jmethodID methodID, va_list &args);
  static bool callCharMethod(JNIEnv *env, jchar &result, jobject obj,
                             jmethodID methodID, ...);
  static bool callShortMethod(JNIEnv *env, jshort &result, jobject obj,
                             jmethodID methodID, va_list &args);
  static bool callShortMethod(JNIEnv *env, jshort &result, jobject obj,
                             jmethodID methodID, ...);
  static bool callIntMethod(JNIEnv *env, jint &result, jobject obj,
                            jmethodID methodID, va_list &args);
  static bool callIntMethod(JNIEnv *env, jint &result, jobject obj,
                            jmethodID methodID, ...);
  static bool callLongMethod(JNIEnv *env, jlong &result, jobject obj,
                             jmethodID methodID, va_list &args);
  static bool callLongMethod(JNIEnv *env, jlong &result, jobject obj,
                             jmethodID methodID, ...);
  static bool callFloatMethod(JNIEnv *env, jfloat &result, jobject obj,
                              jmethodID methodID, va_list &args);
  static bool callFloatMethod(JNIEnv *env, jfloat &result, jobject obj,
                              jmethodID methodID, ...);
  static bool callDoubleMethod(JNIEnv *env, jdouble &result, jobject obj,
                               jmethodID methodID, va_list &args);
  static bool callDoubleMethod(JNIEnv *env, jdouble &result, jobject obj,
                               jmethodID methodID, ...);
  static bool callVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID,
                             va_list &args);
  static bool callVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...);
  static jstring toString(JNIEnv *env, jobject obj);
  static jstring newString(JNIEnv *env, const jchar *uchars, jsize len);
  static jstring newStringUTF(JNIEnv *env, const char *bytes);
  static bool callStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID,
                                   va_list &args);
  static bool callStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID,
                                   ...);
  static bool callStaticIntMethod(JNIEnv *env, jint &result, jclass cls,
                                  jmethodID methodID, va_list &args);
  static bool callStaticIntMethod(JNIEnv *env, jint &result, jclass cls,
                                  jmethodID methodID, ...);
  static jobject newObject(JNIEnv *env, jclass cls, jmethodID constructor,
                           va_list &args);
  static jobject newObject(JNIEnv *env, jclass cls, jmethodID constructor, ...);
  static jobjectArray newObjectArray(JNIEnv *env, jclass cls, jsize len);
  static jobjectArray newStringArray(JNIEnv *env, jsize len);
  static jbyteArray newByteArray(JNIEnv *env, jsize len);
  static jobject newGlobalRef(JNIEnv *env, jobject obj);
  static jweak newWeakGlobalRef(JNIEnv *env, jobject obj);
  static void deleteGlobalRef(JNIEnv *env, jobject &objref);
  static void deleteWeakGlobalRef(JNIEnv *env, jweak &wobjref);
  static bool isLiveRef(JNIEnv *env, jweak wobjref);
public:
  inline static jclass objectClass();
  inline static jclass stringClass();
  inline static jmethodID toStringMID();
private:
  friend class JVMWrapper; // uses initialize(JNIEnv *env)
  static void initialize(JNIEnv *env);
private:
  static jclass sm_objectClass;
  static jclass sm_stringClass;
  static jmethodID sm_toStringMID;
};

// JNIWrapper :: Inline Member Functions. --------------------------------------

/*!
 * \brief Returns object class.
 *
 * \return object class
 */
inline jclass JNIWrapper::objectClass()
{
  return sm_objectClass;
}

/*!
 * \brief Returns string class.
 *
 * \return string class
 */
inline jclass JNIWrapper::stringClass()
{
  return sm_stringClass;
}

/*!
 * \brief Returns toString method ID.
 *
 * \return toString method ID
 */
inline jmethodID JNIWrapper::toStringMID()
{
  return sm_toStringMID;
}

#endif // JNIWRAPPER_H
